package io.yizoo.core.flow;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.yizoo.business.entity.*;
import io.elm.core.CoreController;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;


import io.elm.core.CoreMapper;
import io.elm.core.DMaker;
import io.yizoo.system.entity.*;
import io.yizoo.system.mapper.sys_flowMapper;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

@RestController
@RequestMapping("/system/flow")
public class FlowEngine extends CoreController {

    @Autowired
    private CoreMapper coreMapper;

    @Autowired
    private sys_flowMapper flowMapper;

    //流程初始化时，获取流程实例
    public fw_flowins InitFlow_GetFlowinsModel(String flow_code, String user_id){

        List<Map<String,Object>> listData = new ArrayList<Map<String,Object>>();
        listData = coreMapper.USelectList(
                new DMaker().Selector
                        .From(fw_flow.class,"info")
                        .putFactorItem("flow_code",flow_code)
                        .Where("and info.code=#{flow_code}","flow_code")
                        .GetFactor()
        );

        if(listData!=null && listData.size()>0){
            Map<String,Object> flowData = listData.get(0);

            fw_flowins flowinsModel = new fw_flowins();

            flowinsModel.setId(UUID.randomUUID().toString());
            flowinsModel.setFlow_id(flowData.get("id").toString());
            flowinsModel.setTitle(flowData.get("title").toString());
            flowinsModel.setRemark(flowData.get("code").toString());
            flowinsModel.setStatus(FlowType.flow_status_running);
            flowinsModel.setSys_createtime(new Date());
            flowinsModel.setSys_createtimestamp("" + System.currentTimeMillis());
            flowinsModel.setSys_createuser(user_id);

            listData = coreMapper.USelectList(
                    new DMaker().Selector
                            .Select("info.ins_code")
                            .From(fw_flowins.class,"info")
                            .putFactorItem("flow_code",flow_code)
                            .Where("and info.remark=#{flow_code}","flow_code")
                            .OrderBy("info.ins_code desc")
                            .Limit("limit 1")
                            .GetFactor()
            );

            //不再手动生成编号，项目框架会在Upert时自动给表的 sys_code 字段赋值。
            //这个自动生成需要表有 sys_code_key 字段，同时需要在sys_code表中指定编号前缀中的一部分（否则这部分会取默认值）
            /*
            String ins_code_num = "000000";
            if(listData!=null && listData.size()>0){
                String[] tt = listData.get(0).get("ins_code").toString().split("_");
                if(tt.length>1){
                    int t = Integer.parseInt(tt[1]);
                    if(t<10){ins_code_num = "0000"+t;}
                    else if(t<100){ins_code_num = "000"+t;}
                    else if(t<1000){ins_code_num = "00"+t;}
                    else if(t<10000){ins_code_num = "0"+t;}
                    else {ins_code_num = ""+t;}
                }
            }
            flowinsModel.setIns_code(flow_code+"_"+ins_code_num);
            */

            return flowinsModel;
        }
        else{
            return null;
        }
    }

    //流程初始化时，获取流程节点实例
    //开始节点、结束节点、首个普通节点，应返回三个节点实例
    public List<fw_flowins_node> InitFlow_GetNodeinsModel(String flow_id, String flowins_id, String user_id){
        List<fw_flowins_node> nodeinsModelList = new ArrayList<fw_flowins_node>();

        List<Map<String,Object>> listData = new ArrayList<Map<String,Object>>();
        listData = coreMapper.USelectList(
                new DMaker().Selector
                        .From(fw_flow_node.class,"info")
                        .putFactorItem("flow_id",flow_id)
                        .Where("and info.flow_id =#{flow_id} and info.node_type in ('start','end')","flow_id")
                        .OrderBy("info.node_type desc")
                        .GetFactor()
        );
        if(listData.size()!=2 || listData.get(0).get("node_type").toString().equals(listData.get(1).get("node_type").toString())){return null;}

        fw_flowins_node nodeinsModel_start = new fw_flowins_node();
        fw_flowins_node nodeinsModel_end = new fw_flowins_node();
        fw_flowins_node nodeinsModel_first = new fw_flowins_node();

        nodeinsModel_start.setId(UUID.randomUUID().toString());
        nodeinsModel_start.setFlowins_id(flowins_id);
        nodeinsModel_start.setTitle(listData.get(0).get("title").toString());
        nodeinsModel_start.setNode_id(listData.get(0).get("id").toString());
        nodeinsModel_start.setNode_type(listData.get(0).get("node_type").toString());
        nodeinsModel_end.setId(UUID.randomUUID().toString());
        nodeinsModel_end.setFlowins_id(flowins_id);
        nodeinsModel_end.setTitle(listData.get(1).get("title").toString());
        nodeinsModel_end.setNode_id(listData.get(1).get("id").toString());
        nodeinsModel_end.setNode_type(listData.get(1).get("node_type").toString());
        nodeinsModelList.add(nodeinsModel_start);
        nodeinsModelList.add(nodeinsModel_end);

        listData = coreMapper.USelectList(
                new DMaker().Selector
                        .Select("node.*")
                        .From(fw_flow_line.class,"line")
                        .LeftJoin(fw_flow_node.class,"node","node.id=line.end_node")
                        .putFactorItem("flow_id",flow_id)
                        .putFactorItem("start_node_id",nodeinsModel_start.getNode_id())
                        .Where("and line.flow_id =#{flow_id} and line.start_node = #{start_node_id}", "flow_id","start_node_id")
                        .GetFactor()
        );
        if(listData.size()!=1){return nodeinsModelList;}

        nodeinsModel_first.setId(UUID.randomUUID().toString());
        nodeinsModel_first.setFlowins_id(flowins_id);
        nodeinsModel_first.setTitle(listData.get(0).get("title").toString());
        nodeinsModel_first.setNode_id(listData.get(0).get("id").toString());
        nodeinsModel_first.setNode_type(listData.get(0).get("node_type").toString());
        nodeinsModel_first.setStatus(FlowType.node_status_running);
        nodeinsModel_first.setRemark(listData.get(0).get("remark")==null?null:listData.get(0).get("remark").toString());
        nodeinsModel_first.setNode_alias(listData.get(0).get("node_alias")==null?null:listData.get(0).get("node_alias").toString());
        nodeinsModel_first.setNode_policy(listData.get(0).get("node_policy")==null?null:listData.get(0).get("node_policy").toString());
        nodeinsModel_first.setUser_policy(listData.get(0).get("user_policy")==null?null:listData.get(0).get("user_policy").toString());
        nodeinsModel_first.setPb_policy(listData.get(0).get("pb_policy")==null?null:listData.get(0).get("pb_policy").toString());
        nodeinsModel_first.setSys_createtime(new Date());
        nodeinsModel_first.setSys_createtimestamp("" + System.currentTimeMillis());
        nodeinsModelList.add(nodeinsModel_first);

        return nodeinsModelList;
    }

    //获取节点参与者
    //调用此函数时，相应节点实例可能尚未存到数据库中，所以需要传入flow_node_id和nodeins_id
    //仅在 需动态指定参与者，而未传入相应参数 时返回 null
    public List<fw_flowins_node_user> GetNodePerson(String flow_node_id, String flowins_id, String nodeins_id,ObjectNode objectData,String token){
        List<Map<String,Object>> listData = new ArrayList<Map<String,Object>>();

        //查找节点对应的check、interface、param，每个fw_flow_node_check_param一行
        listData = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("flow_node_id",flow_node_id)
                        .putFactorItem("flowins_id",flowins_id)
                        .Select("f_inter.id,f_inter.type,f_inter.url,f_inter_param.name as param_name,IfNULL(f_param_ins.param_value,f_check_param.value) as param_value")
                        .From(fw_flow_node_check.class,"node_check")
                        .innerJoin(fw_flow_interface.class,"f_inter","f_inter.id = node_check.iface_id")
                        .innerJoin(fw_flow_interface_param.class,"f_inter_param","f_inter_param.fid = f_inter.ID")
                        .innerJoin(fw_flow_node_check_param.class,"f_check_param","f_check_param.check_id = node_check.ID AND f_check_param.iface_param_id = f_inter_param.id")
                        .LeftJoin(fw_flow_param.class,"f_param","f_param.id = f_check_param.flow_param_id")
                        .LeftJoin(fw_flowins_param.class,"f_param_ins","f_param_ins.flow_param_id = f_param.id and f_param_ins.flowins_id = #{flowins_id}","flowins_id")
                        .Where("and node_check.flow_node_id =#{flow_node_id}","flow_node_id")
                        .OrderBy("f_inter.type,f_inter.id")
                        .GetFactor()
        );
        if(listData.size()==0){return new ArrayList<fw_flowins_node_user>();}

        List<String> interIdList = new ArrayList<String>();
        List<String> interTypeList = new ArrayList<String>();
        List<String> interUrlList = new ArrayList<String>();
        for(int i=0;i<listData.size();i++){
            String interUrl = listData.get(i).get("url").toString();
            if(i==0 || !interUrlList.get(interUrlList.size()-1).equals(interUrl)){
                interIdList.add(listData.get(i).get("id").toString());
                interTypeList.add(listData.get(i).get("type").toString());
                interUrlList.add(interUrl);
            }

            //若需动态指定参与者，而未传入相应参数，那么返回null
            if(interUrl.indexOf("/flow/inter_dynamic")>0){
                if(!objectData.has("dynamic_user_id") || FlowType.getJsonNodeItemTextNull(objectData,"dynamic_user_id")==null){
                    return null;
                }
            }
        }

        List<fw_flowins_node_user> nodeinsUserModelList = new ArrayList<fw_flowins_node_user>();
        for(int i=0;i<interUrlList.size();i++){
            String interId = interIdList.get(i);
            String interType = interTypeList.get(i);
            String interUrl = interUrlList.get(i);

            ObjectNode paramData = new ObjectMapper().createObjectNode();
            for(Map<String,Object> data : listData){
                if(interId.equals(data.get("id").toString())){
                    String param_name = data.get("param_name").toString();
                    String param_value = null;
                    if(data.get("param_value")!=null){
                        param_value = data.get("param_value").toString();
                        if(!paramData.has(param_name)){ paramData.put(param_name,param_value); }
                        else{ paramData.put(param_name,paramData.get(param_name).asText()+","+param_value); }
                    }
                    //以传入的参数值（如果有）为最优先，此时之前查到的参数值（如果有）被覆盖
                    if(objectData.has(param_name)){paramData.put(param_name,objectData.get(param_name).asText()); }
                }
            }

            String rStr = null;
            String paramJsonStr = paramData.toString();
            if(interType.equals("0")){
                //访问本地预置接口，不用发起post请求，直接访问
                if(interUrl.indexOf("/flow/inter_org")>0){ rStr = inter_org(paramJsonStr); }
                else if(interUrl.indexOf("/flow/inter_role")>0){ rStr = inter_role(paramJsonStr); }
                else if(interUrl.indexOf("/flow/inter_user")>0){ rStr = inter_user(paramJsonStr); }
                else if(interUrl.indexOf("/flow/inter_zjsj")>0){ rStr = inter_zjsj(paramJsonStr); }
                else if(interUrl.indexOf("/flow/inter_flow_creater")>0){ rStr = inter_flow_creater(paramJsonStr); }
                else if(interUrl.indexOf("/flow/inter_dynamic")>0){ rStr = inter_dynamic(paramJsonStr); }
            }
            else{
                HashMap<String,String> pResult = sendPost(interUrl,token,paramJsonStr);
                if(pResult.get("status").equals("success") && pResult.get("data")!=null && pResult.get("data")!="null"){
                    rStr = pResult.get("data");
                }
            }

            if(rStr!=null){
                System.out.println("访问参与者接口成功 - "+interUrl);
                try{
                    ArrayNode uList = (ArrayNode) (new ObjectMapper().readTree(rStr));
                    for(JsonNode u : uList){
                        fw_flowins_node_user uModel = new fw_flowins_node_user();
                        uModel.setUser_id(u.get("user_id").asText());
                        uModel.setUser_type(u.get("user_type").asText());

                        nodeinsUserModelList.add(uModel);
                    }
                }
                catch (Exception e){e.printStackTrace();}
            }
            else{
                System.out.println("访问参与者接口失败 - "+interUrl+" - param:"+paramData.toString());
            }
        }

        for(fw_flowins_node_user uModel : nodeinsUserModelList){
            uModel.setId(UUID.randomUUID().toString());
            uModel.setNodeins_id(nodeins_id);
            uModel.setStatus(FlowType.node_user_status_running);
        }

        return nodeinsUserModelList;
    }

    //根据连线条件和节点是否已经实例化，判断节点是否可被实例化
    public String StartNodeByLineCondition_Check(String condition,String flowins_id,String node_id,ObjectNode data){

        //判断连线条件
        boolean conditionAllowed = false;
        if(condition==null || condition==""){conditionAllowed = true;}
        else{
            //条件语句示例： ####@col_2####>=####5####||####@col_1####>=####200
            boolean conditionCheck = true;
            String[] wordList = condition.split("####");
            String conditionStr = "";

            Map<String, Object> secFormData = new HashMap<String, Object>();
            Map<String, String> secFormColTypeData = new HashMap<String, String>();
            if(condition.indexOf("@")>=0){
                Map<String,Object> sfData = FlowsecFormItem_GetTableInfoByFlowinsId(flowins_id);
                if(sfData!=null){
                    String table_name = sfData.get("table_name").toString();
                    Map<String,Object> pData = new HashMap<String,Object>();
                    pData.put("table_name",table_name);
                    pData.put("flowins_id",flowins_id);
                    List<Map<String, Object>> sfList = flowMapper.FlowSecFormTable_SelectByFlowinsId(pData);
                    if(sfList.size()==1){
                        secFormData = sfList.get(0);
                    }

                    ArrayNode tData = Ctor.getArrayNode(sfData.get("table_column").toString());
                    for(JsonNode tItem :tData){
                        secFormColTypeData.put(tItem.get("column_name").asText(),tItem.get("type").asText());
                    }
                }
            }

            //处理中文的加减乘除符号,处理流程发起者名称,处理列名
            for(int i=0;i<wordList.length && conditionCheck;i++){
                String word = wordList[i];
                word = word.trim();//从首尾位置去除空格等空白字符
                if(word.equals("＋")){word="+";}
                else if(word.equals("－")){word="-";}
                else if(word.equals("×")){word="*";}
                else if(word.equals("÷")){word="/";}
                else if(word.equals("flowins_creater")){
                    List<Map<String,Object>> nameList = coreMapper.USelectList(
                            new DMaker().Selector
                                    .putFactorItem("flowins_id",flowins_id)
                                    .Select("ei.name")
                                    .From(fw_flowins.class,"info")
                                    .innerJoin(sys_user.class,"uu","uu.id = info.sys_createuser")
                                    .innerJoin(biz_hrm_ei_basic.class,"ei","ei.emp_code = uu.emp_code")
                                    .Where("AND info.id=#{flowins_id}","flowins_id")
                                    .GetFactor()
                    );
                    if(nameList.size()!=1){ conditionCheck=false;}
                    else{ word = nameList.get(0).get("name").toString(); }
                }
                else if(word.indexOf("@")==0){
                    String colName = word.replaceFirst("@","");
                    if(secFormData.containsKey(colName) && secFormColTypeData.containsKey(colName)){
                        word = secFormData.get(colName).toString();
                        String colType = secFormColTypeData.get(colName).toString();

                        boolean isText = true;
                        if( word.matches("-?\\d+(\\.\\d+)?") ){ isText=false; }
                        else if(colType.equals("date") || colType.equals("time") || colType.equals("datetime")){
                            if(i>0 && i<wordList.length && !(wordList[i-1].contains("包含"))  && !(wordList[i+1].contains("包含"))){
                                word = "new Date('"+word+"')";

                                isText = false;
                            }
                        }

                        if(isText){ word = '"' + word + '"'; }
                    }
                    else{ word = "null"; }
                }

                wordList[i] = word;
            }
            //处理 '包含'、'不包含'
            for(int i=0;i<wordList.length && conditionCheck;i++){
                String word = wordList[i];

                if(word.equals("包含") || word.equals("不包含")){
                    if(i==0 || i==wordList.length){ conditionCheck=false; }
                    else {
                        if(!wordList[i-1].startsWith("\"")){wordList[i-1] = '"'+wordList[i-1]+'"';}
                        if(!wordList[i+1].startsWith("\"")){wordList[i+1] = '"'+wordList[i+1]+'"';}

                        wordList[i] = ".indexOf(";
                        if(word.equals("包含")){ wordList[i+1] = wordList[i+1]+")>=0"; }
                        if(word.equals("不包含")){ wordList[i-1] = wordList[i+1]+")<0"; }
                    }
                }
            }
            //处理日期加减情况
            for(int i=0;i<wordList.length && conditionCheck;i++){
                String word = wordList[i];

                if(word.startsWith("new Date('")){
                    if(i>=(wordList.length-2)){conditionCheck=false;}
                    else if(!(wordList[i+1].equals("-")) || !(wordList[i+2].startsWith("new Date('"))){conditionCheck=false;}
                    else{
                        wordList[i] = "((" + wordList[i];
                        wordList[i+2] = wordList[i+2]+")/(1000 * 60 * 60 * 24))";
                        i = i+2;
                    }
                }
            }

            for(int i=0;i<wordList.length && conditionCheck;i++){
                conditionStr = conditionStr + wordList[i];
            }
            condition = conditionCheck?conditionStr:"false";
            System.out.println("【AAAA】 LineCondtion: " + condition);

            //若条件语句含有流程参数，从流程参数实例中取相应的值
            /*
            if(condition.contains("@")){
                List<Map<String,Object>> paramDatalist = coreMapper.USelectList(
                        new DMaker().Selector
                                .putFactorItem("flowins_id",flowins_id)
                                .Select("param_name,param_value")
                                .From(fw_flowins_param.class)
                                .Where("AND flowins_id=#{flowins_id}","flowins_id")
                                .GetFactor()
                );
                if(paramDatalist.size()>0){
                    for(Map<String,Object> paramData : paramDatalist){
                        if(paramData.get("param_name")!=null && paramData.get("param_value")!=null){
                            String param_name = paramData.get("param_name").toString();
                            String param_value = "'" + paramData.get("param_value").toString() + "'";
                            if(data.has(param_name) && data.get(param_name)!=null){
                                param_value = "'" + data.get(param_name).asText() + "'";
                            }

                            param_name = "@" + paramData.get("param_name").toString();
                            condition = condition.replaceAll(param_name,param_value);
                        }
                    }
                }
            }
            if(condition.contains("@")){
                System.out.println("【AAAA】连线条件缺少参数值 -- " + condition);
                return "wrongWhenCheckLineCondition_NeedParam--"+condition;
            }
            */

            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("js");
            try {
                conditionAllowed = (boolean) engine.eval(condition);
            }
            catch (Exception e){
                e.printStackTrace();
                System.out.println("【AAAA】连线条件判断出错 -- " + condition);
                return "wrongWhenCheckLineCondition--"+condition;
            }
        }
        if(!conditionAllowed){
            System.out.println("【AAAA】连线条件判断为false -- " + condition);
            return "no_lineConditionFalse";
        }
        else{ System.out.println("【AAAA】连线条件判断为true -- " + condition); }

        //判断节点是否已实例化
        List<Map<String,Object>> checklist = new ArrayList<Map<String,Object>>();
        checklist = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("flowins_id",flowins_id)
                        .putFactorItem("node_id",node_id)
                        .Select("id,status")
                        .From(fw_flowins_node.class)
                        .Where("AND flowins_id=#{flowins_id} AND node_id=#{node_id}","flowins_id","node_id")
                        .GetFactor()
        );
        if(checklist.size()>0){
            System.out.println("【AAAA】连线指向已实例化的节点--nodeins_id" + checklist.get(0).get("id").toString());

            String rStr = "no_nodeInsExist--" + checklist.get(0).get("id").toString();
            rStr = rStr+"--"+(checklist.get(0).get("status")==null?"noStatus":checklist.get(0).get("status").toString());
            return rStr;
        }

        return "yes";
    }

    //根据节点实例id，更新流程参数实例
    @Transactional
    public boolean UpdateFlowinsParamByNodeinsId(String nodeins_id, ObjectNode data){
        List<Map<String,Object>> paramDatalist = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("nodeins_id",nodeins_id)
                        .Select("nodeins.flowins_id,flowins.flow_id")
                        .From(fw_flowins_node.class,"nodeins")
                        .LeftJoin(fw_flowins.class,"flowins","flowins.id = nodeins.flowins_id")
                        .Where("AND nodeins.id=#{nodeins_id}","nodeins_id")
                        .GetFactor()
        );
        if(paramDatalist.size()==0){return true;}

        String flow_id = paramDatalist.get(0).get("flow_id").toString();
        String flowins_id = paramDatalist.get(0).get("flowins_id").toString();

        return UpdateFlowinsParam(flow_id,flowins_id,data);
    }
    //更新流程参数实例
    //不要求流程已实例化，按flow_id查找模板信息，用传入的flowins_id作为参数实例的相应字段值
    @Transactional
    public boolean UpdateFlowinsParam(String flow_id,String flowins_id, ObjectNode data){
        List<Map<String,Object>> paramDatalist = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("flow_id",flow_id)
                        .putFactorItem("flowins_id",flowins_id)
                        .Select("param.id,param.param_name,param.param_value,param.param_type,param.param_explain,param_ins.id AS param_ins_id")
                        .From(fw_flow_param.class,"param")
                        .LeftJoin(fw_flowins_param.class,"param_ins","param_ins.flow_param_id = param.id AND param_ins.flowins_id=#{flowins_id}","flowins_id")
                        .Where("AND param.flow_id=#{flow_id}","flow_id")
                        .GetFactor()
        );
        if(paramDatalist.size()==0){return true;}

        List<fw_flowins_param> paramModelList = new ArrayList<fw_flowins_param>();
        for(Map<String,Object> paramData : paramDatalist){
            String param_name = paramData.get("param_name").toString();

            String param_value = null;
            if(data.has(param_name) && data.get(param_name).asText()!=null){
                param_value = data.get(param_name).asText();
            }
            else if(paramData.get("param_ins_id")==null && paramData.get("param_value")!=null){
                param_value = paramData.get("param_value").toString();
            }

            if(param_value!=null){
                fw_flowins_param paramModel = new fw_flowins_param();
                if(paramData.get("param_ins_id")!=null){
                    paramModel.setId(paramData.get("param_ins_id").toString());
                    paramModel.setParam_value(param_value);
                }
                else{
                    paramModel.setId(UUID.randomUUID().toString());
                    paramModel.setFlowins_id(flowins_id);
                    paramModel.setFlow_param_id(paramData.get("id").toString());
                    paramModel.setParam_value(param_value);
                    String param_type = paramData.get("param_type")==null?null:paramData.get("param_type").toString();
                    String param_explain = paramData.get("param_explain")==null?null:paramData.get("param_explain").toString();
                    paramModel.setParam_name(param_name);
                    paramModel.setParam_type(param_type);
                    paramModel.setParam_explain(param_explain);
                }
                paramModelList.add(paramModel);

                System.out.println("【AAAA】设置流程参数实例：" + param_name + " - " + param_value);
            }
        }

        if(paramModelList.size()>0){Ctor.HMapper.Save(paramModelList,null);}

        return true;
    }

    public fw_flowins_node_log CreateNodeLogModel(fw_flowins_node nodeinsModel ,String user_id,int addMillisecondNum){
        if(nodeinsModel==null){return null;}

        fw_flowins_node_log model = new fw_flowins_node_log();
        model.setId(UUID.randomUUID().toString());
        model.setNodeins_id(nodeinsModel.getId());
        model.setStatus(nodeinsModel.getStatus());
        model.setStatus_user(user_id);
        model.setStatus_time(new Date());
        model.setStatus_timestamp("" + ( System.currentTimeMillis() + addMillisecondNum ));

        return model;
    }
    public List<fw_flowins_node_log> CreateNodeLogModelList(List<fw_flowins_node> nodeinsModelList ,String user_id,int addMillisecondNum){
        if(nodeinsModelList==null){return null;}

        List<fw_flowins_node_log> modelList = new ArrayList<fw_flowins_node_log>();
        for(fw_flowins_node nodeinsModel: nodeinsModelList){
            if(nodeinsModel==null){ return null; }
            else{ modelList.add(CreateNodeLogModel(nodeinsModel,user_id,addMillisecondNum)); }
        }

        return modelList;
    }

    /**
     * 向指定URL发送GET方法的请求
     * @param url   发送请求的URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public Object sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

    public HashMap<String, String> sendPost(String url,String token, String jsonStr) {
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpClient client = HttpClients.createDefault();

        StringEntity entity = new StringEntity(jsonStr, "UTF-8");//请求参数转JOSN字符串
        entity.setContentEncoding("UTF-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        if(token!=null && !token.equals("")){
            httpPost.setHeader("Authorization","Bearer "+token);
        }

        HashMap<String, String> result = new HashMap<String, String>();
        try {
            HttpResponse response = client.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                String rStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                result.put("status","success");
                result.put("data",rStr);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("status","error");
            result.put("data","");
        }

        //关闭连接
        try {client.close();}
        catch (Exception e) {System.out.println(e.getMessage());}

        return result;
    }

    @Transactional
    public boolean DeleteFlowins(String data_id) {
        List<Map<String,Object>> yw = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("data_id",data_id)
                        .Select("flow_id")
                        .From(fw_flowins_yw.class)
                        .Where("AND data_id=#{data_id}","data_id")
                        .GetFactor()
        );
        if(yw.size()==0){return true;}

        String flowins_id = yw.get(0).get("flow_id").toString();
        Ctor.CoreMapper.UDelete(
                Ctor.DMaker().Deleter
                        .putFactorItem("flowins_id",flowins_id)
                        .From(fw_flowins.class)
                        .Where("AND id = #{flowins_id} ", "flowins_id")
                        .GetFactor());
        Ctor.CoreMapper.UDelete(
                Ctor.DMaker().Deleter
                        .putFactorItem("flowins_id",flowins_id)
                        .From(fw_flowins_yw.class)
                        .Where("AND flow_id = #{flowins_id} ", "flowins_id")
                        .GetFactor());
        Ctor.CoreMapper.UDelete(
                Ctor.DMaker().Deleter
                        .putFactorItem("flowins_id",flowins_id)
                        .From(fw_flowins_param.class)
                        .Where("AND flowins_id = #{flowins_id} ", "flowins_id")
                        .GetFactor());
        Ctor.CoreMapper.UDelete(
                Ctor.DMaker().Deleter
                        .putFactorItem("flowins_id",flowins_id)
                        .From(fw_flowins_line.class)
                        .Where("AND flowins_id = #{flowins_id} ", "flowins_id")
                        .GetFactor());
        Ctor.CoreMapper.UDelete(
                Ctor.DMaker().Deleter
                        .putFactorItem("flowins_id",flowins_id)
                        .From(fw_flowins_node_user.class)
                        .Where("AND nodeins_id IN (SELECT id FROM fw_flowins_node WHERE flowins_id = #{flowins_id}) ", "flowins_id")
                        .GetFactor());
        Ctor.CoreMapper.UDelete(
                Ctor.DMaker().Deleter
                        .putFactorItem("flowins_id",flowins_id)
                        .From(fw_flowins_node_log.class)
                        .Where("AND nodeins_id IN (SELECT id FROM fw_flowins_node WHERE flowins_id = #{flowins_id})  ", "flowins_id")
                        .GetFactor());
        Ctor.CoreMapper.UDelete(
                Ctor.DMaker().Deleter
                        .putFactorItem("flowins_id",flowins_id)
                        .From(fw_flowins_node_back.class)
                        .Where("AND from_nodeins IN (SELECT id FROM fw_flowins_node WHERE flowins_id = #{flowins_id}) ", "flowins_id")
                        .GetFactor());
        Ctor.CoreMapper.UDelete(
                Ctor.DMaker().Deleter
                        .putFactorItem("flowins_id",flowins_id)
                        .From(fw_flowins_node.class)
                        .Where("AND flowins_id = #{flowins_id} ", "flowins_id")
                        .GetFactor());

        return true;
    }

    //分页查找用户待办已办，每个节点实例一行
    public Map<String, Object> GetUserTask(String flow_code,String user_id,int pageSize,int pageNum) {
        int min_index = (pageNum-1) * pageSize;
        if(min_index<0){min_index=0;}
        int index_num = pageSize;

        Map<String,Object> ff = new HashMap<String,Object>();
        ff.put("flow_code",flow_code);
        ff.put("user_id",user_id);
        ff.put("data_id","nothing");
        ff.put("min_index",min_index);
        ff.put("index_num",index_num);
        List<Map<String, Object>> flowDataList = flowMapper.GetUserTask(ff);
        List<Map<String, Object>> countData = flowMapper.GetUserTaskCount(ff);

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("pagedata",flowDataList);
        result.put("count",Integer.parseInt(countData.get(0).get("count").toString()));

        return result;
    }

    //查找指定节点实例的参与者信息
    public List<Map<String,Object>> SearchNodeinsPerson(String nodeins_id){
        Map<String,Object> ff = new HashMap<String,Object>();
        ff.put("nodeins_id",nodeins_id);
        List<Map<String,Object>> nodePersonList = flowMapper.SearchNodeinsPerson(ff);
        return nodePersonList;
    }

    //判断user_id，是否是指定的运行中的节点实例下的运行中的参与者
    public boolean IsRunningNodeRunningPerson(String nodeins_id,String user_id){
        List<Map<String,Object>> nuDataList = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("nodeins_id",nodeins_id)
                        .Select("person.user_id,person.user_type")
                        .From(fw_flowins_node.class,"nodeins")
                        .innerJoin(fw_flowins_node_user.class,"person","person.nodeins_id = nodeins.id AND person.status='running'")
                        .Where("AND nodeins.status='running' AND nodeins.id =#{nodeins_id}","nodeins_id")
                        .GetFactor()
        );
        if(nuDataList.size()==0){return false;}

        List<fw_flowins_node_user> nuList = new ArrayList<fw_flowins_node_user>();
        for(Map<String,Object> nuData : nuDataList){
            fw_flowins_node_user nu = new fw_flowins_node_user();
            nu.setUser_id(nuData.get("user_id").toString());
            nu.setUser_type(nuData.get("user_type").toString());
            nuList.add(nu);
        }

        return IsNodeRunningPerson(nuList,user_id);
    }
    //判断节点参与者实例，是否包含对应的user_id
    public boolean IsNodeRunningPerson(List<fw_flowins_node_user> nuList,String user_id){
        List<Map<String,Object>> check = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("user_id",user_id)
                        .Select("uu.dept_id AS org_id,rr.role_id")
                        .From(sys_user.class,"uu")
                        .LeftJoin(sys_role_rel_user.class,"rr","rr.user_id = uu.id")
                        .Where("AND uu.id =#{user_id}","user_id")
                        .GetFactor()
        );
        if(check.size()==0){return false;}
        String org_id =check.get(0).get("org_id").toString();
        List<String> role_id_list = new ArrayList<String>();
        for(Map<String,Object> cc :check){role_id_list.add(cc.get("role_id").toString());}

        List<Map<String,Object>> checkXj = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("user_id",user_id)
                        .Select("IFNULL(uu_xj.id,'nothing') AS xj_id")
                        .From(sys_user.class,"uu")
                        .LeftJoin(biz_hrm_ei_basic.class,"bb","bb.emp_code = uu.emp_code")
                        .LeftJoin(biz_hrm_ei_rel_org.class,"rr","rr.ei_id = bb.id AND rr.fzr = 1")
                        .LeftJoin(biz_hrm_ei_rel_org.class,"rr_xj","rr_xj.org_id = rr.org_id AND rr_xj.pm = 1")
                        .LeftJoin(biz_hrm_ei_basic.class,"bb_xj","bb_xj.id = rr_xj.ei_id")
                        .LeftJoin(sys_user.class,"uu_xj","uu_xj.emp_code = bb_xj.emp_code")
                        .Where("AND uu.id =#{user_id}","user_id")
                        .GetFactor()
        );
        List<String> xj_id_list = new ArrayList<String>();
        for(Map<String,Object> xj :checkXj){xj_id_list.add(xj.get("xj_id").toString());}

        for(fw_flowins_node_user person : nuList){
            //System.out.println("CCCCC "+person.getUser_type()+"  "+person.getUser_id());
            String ppType = person.getUser_type();
            String ppId = ","+person.getUser_id()+",";
            if(ppType.equals(FlowType.node_user_type_user)){
                if((ppId).contains(","+user_id+",")){return true;}
            }
            else if(ppType.equals(FlowType.node_user_type_org)){
                if((ppId).contains(","+org_id+",")){return true;}
            }
            else if(ppType.equals(FlowType.node_user_type_role)){
                for(String role_id:role_id_list){if((ppId).contains(","+role_id+",")){return true;}}
            }
            else if(ppType.equals(FlowType.node_user_type_zjsj)){
                for(String xj_id:xj_id_list){if((ppId).contains(","+xj_id+",")){return true;}}
            }
        }
        return false;
    }

    //为表单表数据添加部门、账号、人员关联(若有有对应的表单项)
    public List<Map<String, Object>> attachSecFromSomeInfo(String flow_code,List<Map<String,Object>> dataList){
        List<Map<String,Object>> checkList = Ctor.CoreMapper.USelect(
                Ctor.DMaker().Selector
                        .putFactorItem("flow_code",flow_code)
                        .Select("ff.table_column")
                        .From(fw_flow.class,"flow")
                        .innerJoin(fw_flowsec_form.class,"ff","ff.flow_id = flow.id")
                        .Where("and flow.code = #{flow_code}","flow_code")
                        .GetFactor());
        if(checkList.size()!=1){return dataList;}

        String table_column = checkList.get(0).get("table_column").toString();

        int tNum = 0;
        List<Map<String,Object>> userList = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> orgList = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> eiList = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> carList = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> xsList = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> sjList = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> puList = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> xmList = new ArrayList<Map<String,Object>>();
        if(table_column.contains("select_user")){
            userList = Ctor.CoreMapper.USelect(
                    Ctor.DMaker().Selector
                            .Select("id,nick_name AS name")
                            .From(sys_user.class)
                            .GetFactor());
            tNum++;
        }
        if(table_column.contains("select_org")){
            orgList = Ctor.CoreMapper.USelect(
                    Ctor.DMaker().Selector
                            .Select("id,name")
                            .From(sys_org.class)
                            .GetFactor());
            tNum++;
        }
        if(table_column.contains("select_ei")){
            eiList = Ctor.CoreMapper.USelect(
                    Ctor.DMaker().Selector
                            .Select("id,name,emp_code")
                            .From(biz_hrm_ei_basic.class)
                            .GetFactor());
            tNum++;
        }
        if(table_column.contains("select_car")){
            carList = Ctor.CoreMapper.USelect(
                    Ctor.DMaker().Selector
                            .Select("id,license_plate AS name")
                            .From(biz_tms_car.class)
                            .GetFactor());
            tNum++;
        }
        if(table_column.contains("select_input_xs")){
            xsList = Ctor.CoreMapper.USelect(
                    Ctor.DMaker().Selector
                            .Select("t.kh_name as select_name,t.sys_code_key as select_id")
                            .From(biz_crm_lead.class,"t")
                            .LeftJoin(biz_hrm_ei_basic.class,"a","a.emp_code=t.fzxs")
                            .GetFactor());
            tNum++;
        }
        if(table_column.contains("select_input_sj")){
            sjList = Ctor.CoreMapper.USelect(
                    Ctor.DMaker().Selector
                            .Select("t.name as select_name,t.sys_code_key as select_id")
                            .From(biz_crm_opportunity.class,"t")
                            .LeftJoin(biz_hrm_ei_basic.class,"a","a.emp_code=t.fzxs")
                            .GetFactor());
            tNum++;
        }
        if(table_column.contains("select_input_pu")){
            puList = Ctor.CoreMapper.USelect(
                    Ctor.DMaker().Selector
                            .Select("t.purpose as select_name,t.sys_code_key as select_id")
                            .From(biz_wms_purchase.class,"t")
                            .LeftJoin(biz_hrm_ei_basic.class,"a","a.emp_code=t.purchaser_name")
                            .GetFactor());
            tNum++;
        }
        if(table_column.contains("select_input_pj")){
            xmList = Ctor.CoreMapper.USelect(
                    Ctor.DMaker().Selector
                            .Select("a.name as select_name, a.sys_code_key as select_id")
                            .From(biz_pmis_pj.class, "a")
                            .GetFactor());
            tNum++;
        }
        
        if(tNum==0){return dataList;}

        ArrayNode tData = Ctor.getArrayNode(table_column);
        for(Map<String,Object> data : dataList){
            for(JsonNode tItem :tData){
                String column_name = tItem.get("column_name").asText();
                if(tItem.get("type").asText().equals("select_user")){
                    if(data.get(column_name)!=null){
                        for(Map<String,Object> uData :userList){
                            if(uData.get("id").toString().equals(data.get(column_name).toString())){
                                data.put(column_name+"_str",uData.get("name").toString());
                            }
                        }
                    }
                }
                if(tItem.get("type").asText().equals("select_org")){
                    if(data.get(column_name)!=null){
                        for(Map<String,Object> oData :orgList){
                            if(oData.get("id").toString().equals(data.get(column_name).toString())){
                                data.put(column_name+"_str",oData.get("name").toString());
                            }
                        }
                    }
                }
                if(tItem.get("type").asText().equals("select_ei")){
                    if(data.get(column_name)!=null){
                        for(Map<String,Object> eData :eiList){
                            if(eData.get("emp_code").toString().equals(data.get(column_name).toString())){
                                data.put(column_name+"_str",eData.get("name").toString());
                            }
                        }
                    }
                }
                if(tItem.get("type").asText().equals("select_car")){
                    if(data.get(column_name)!=null){
                        for(Map<String,Object> carData :carList){
                            if(carData.get("id").toString().equals(data.get(column_name).toString())){
                                data.put(column_name+"_str",carData.get("name").toString());
                            }
                        }
                    }
                }
                if(tItem.get("type").asText().equals("select_input_xs")){
                    if(data.get(column_name)!=null){
                        for(Map<String,Object> xsData :xsList){
                            if(xsData.get("select_id").toString().equals(data.get(column_name).toString())){
                                data.put(column_name+"_str",xsData.get("select_name").toString());
                            }
                        }
                    }
                }
                if(tItem.get("type").asText().equals("select_input_sj")){
                    if(data.get(column_name)!=null){
                        for(Map<String,Object> sjData :sjList){
                            if(sjData.get("select_id").toString().equals(data.get(column_name).toString())){
                                data.put(column_name+"_str",sjData.get("select_name").toString());
                            }
                        }
                    }
                }
                if(tItem.get("type").asText().equals("select_input_pu")){
                    if(data.get(column_name)!=null){
                        for(Map<String,Object> sjData :puList){
                            if(sjData.get("select_id").toString().equals(data.get(column_name).toString())){
                                data.put(column_name+"_str",sjData.get("select_name").toString());
                            }
                        }
                    }
                }
                if(tItem.get("type").asText().equals("select_input_pj")){
                    if(data.get(column_name)!=null){
                        for(Map<String,Object> xmData :xmList){
                            if(xmData.get("select_id").toString().equals(data.get(column_name).toString())){
                                data.put(column_name+"_str",xmData.get("select_name").toString());
                            }
                        }
                    }
                }
            }
        }

        return dataList;
    }

    //为业务数据添加流程数据关联
    //若一个用户同时是单个流程实例中多个运行中节点参与者，那么设置的nodeins_id、nodeins_title、nodeins_status、preson_status的内容会用 --- 分隔多个值
    public List<Map<String, Object>> attachUserTask(String flow_code,String user_id,List<Map<String,Object>> dataList,int pageSize,int pageNum) {
        if(dataList==null || dataList.size()==0){ return dataList;}

        int min_index = (pageNum-1) * pageSize;
        if(min_index<0){min_index=0;}
        int index_num = pageSize;

        String data_id = "";
        for(Map<String,Object> data :dataList){
            data_id = data_id + ","+ data.get("id").toString();
        }
        data_id = "," + data_id + ",";

        Map<String,Object> ff = new HashMap<String,Object>();
        ff.put("flow_code",flow_code);
        ff.put("user_id",user_id);
        ff.put("data_id",data_id);
        ff.put("min_index",min_index);
        ff.put("index_num",index_num);
        List<Map<String, Object>> flowDataList = flowMapper.GetUserTask(ff);
        //List<Map<String, Object>> countData = flowMapper.GetUserTaskCount(ff);

        for(Map<String,Object> data :dataList){
            for(Map<String,Object> flowData :flowDataList){
                String flow_status = null;
                String sys_code_key = null;
                String nodeins_id = null;
                String nodeins_title = null;
                String nodeins_status = null;
                String preson_status = null;
                String bStr = "---";
                if(data.get("id").equals(flowData.get("data_id"))){
                    if(flow_status==null){flow_status = flowData.get("flow_status").toString();}
                    if(sys_code_key==null && flowData.get("sys_code_key")!=null){sys_code_key =flowData.get("sys_code_key").toString();}

                    if(
                            flowData.get("nodeins_status").equals(FlowType.node_status_running)
                                    &&
                                    flowData.get("preson_status").equals(FlowType.node_user_status_running)
                    ){
                        if(nodeins_id==null){
                            nodeins_id = flowData.get("nodeins_id").toString();
                            nodeins_title = flowData.get("nodeins_title").toString();
                            nodeins_status = flowData.get("nodeins_status").toString();
                            preson_status = flowData.get("preson_status").toString();
                        }
                        else{
                            nodeins_id = nodeins_id + bStr + flowData.get("nodeins_id").toString();
                            nodeins_title =  nodeins_title + bStr + flowData.get("nodeins_title").toString();
                            nodeins_status =  nodeins_status + bStr + flowData.get("nodeins_status").toString();
                            preson_status =  preson_status + bStr + flowData.get("preson_status").toString();
                        }
                    }
                    else if(nodeins_id==null){
                        nodeins_id = flowData.get("nodeins_id").toString();
                        nodeins_title = flowData.get("nodeins_title").toString();
                        nodeins_status = flowData.get("nodeins_status").toString();
                        preson_status = flowData.get("preson_status").toString();
                    }
                }

                if(flow_status!=null){data.put("flow_status",flow_status);}
                if(sys_code_key!=null){data.put("sys_code_key",sys_code_key);}
                if(nodeins_id!=null){data.put("nodeins_id",nodeins_id);}
                if(nodeins_title!=null){data.put("nodeins_title",nodeins_title);}
                if(nodeins_status!=null){data.put("nodeins_status",nodeins_status);}
                if(preson_status!=null){data.put("preson_status",preson_status);}
            }
        }

        return dataList;
    }

    //根据流程编码，查找关联的表单表名
    public String FlowsecFormItem_GetTableName(String flow_code){
        List<Map<String,Object>> checkList = Ctor.CoreMapper.USelect(
                new DMaker().Selector
                        .putFactorItem("flow_code",flow_code)
                        .Select("ff.table_name")
                        .From(fw_flow.class,"flow")
                        .innerJoin(fw_flowsec_form.class,"ff","ff.flow_id = flow.id")
                        .Where("and flow.code = #{flow_code}","flow_code")
                        .GetFactor());
        if(checkList.size()!=1){return null;}
        return checkList.get(0).get("table_name").toString();
    }
    //根据流程实例ID，查找关联的表单表名
    public Map<String, Object> FlowsecFormItem_GetTableInfoByFlowinsId(String flowins_id){
        List<Map<String,Object>> checkList = Ctor.CoreMapper.USelect(
                new DMaker().Selector
                        .putFactorItem("flowins_id",flowins_id)
                        .Select("ff.table_name,ff.table_column")
                        .From(fw_flowins.class,"flowins")
                        .innerJoin(fw_flowsec_form.class,"ff","ff.flow_id = flowins.flow_id")
                        .Where("and flowins.id = #{flowins_id}","flowins_id")
                        .GetFactor());
        if(checkList.size()!=1){return null;}
        return checkList.get(0);
    }

    //参与者接口
    public String inter_user( String jsonStr) {
        String userType = FlowType.node_user_type_user;
        String result = "[]";

        System.out.println("【AAAA】 inter_user - jsonStr:"+jsonStr);

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode data = null;
        try{
            data = (ObjectNode)mapper.readTree(jsonStr);
        }
        catch (IOException e) {
            e.printStackTrace();
            return result;
        }

        String f_param_user_id = FlowType.getJsonNodeItemTextNull(data,"f_param_user_id");
        if(f_param_user_id==null){return null;}
        String id_str = ","+f_param_user_id+",";
        List<Map<String,Object>> dList = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("id_str",id_str)
                        .Select("id")
                        .From(sys_user.class)
                        .Where("and INSTR(#{id_str}, CONCAT(CONCAT(',',ID),',')) > 0","id_str")
                        .GetFactor()
        );
        ArrayNode rList = mapper.createArrayNode();
        for(Map<String,Object> d : dList){
            ObjectNode r = mapper.createObjectNode();
            r.put("user_id",d.get("id").toString());
            r.put("user_type",userType);
            rList.add(r);
        }
        result = rList.toString();
        return result;
    }

    //参与者接口
    public String inter_org( String jsonStr) {
        String userType = FlowType.node_user_type_org;
        String result = "[]";

        System.out.println("【AAAA】 inter_org - jsonStr:"+jsonStr);

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode data = null;
        try{
            data = (ObjectNode)mapper.readTree(jsonStr);
        }
        catch (IOException e) {
            e.printStackTrace();
            return result;
        }

        String f_param_org_id = FlowType.getJsonNodeItemTextNull(data,"f_param_org_id");
        if(f_param_org_id==null){return null;}
        String id_str = ","+f_param_org_id+",";
        List<Map<String,Object>> dList = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("id_str",id_str)
                        .Select("id")
                        .From(sys_org.class)
                        .Where("and INSTR(#{id_str}, CONCAT(CONCAT(',',ID),',')) > 0","id_str")
                        .GetFactor()
        );
        ArrayNode rList = mapper.createArrayNode();
        for(Map<String,Object> d : dList){
            ObjectNode r = mapper.createObjectNode();
            r.put("user_id",d.get("id").toString());
            r.put("user_type",userType);
            rList.add(r);
        }
        result = rList.toString();
        return result;
    }

    //参与者接口
    public String inter_role( String jsonStr) {
        String userType = FlowType.node_user_type_role;
        String result = "[]";

        System.out.println("【AAAA】 inter_role - jsonStr:"+jsonStr);

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode data = null;
        try{
            data = (ObjectNode)mapper.readTree(jsonStr);
        }
        catch (IOException e) {
            e.printStackTrace();
            return result;
        }

        String f_param_role_id = FlowType.getJsonNodeItemTextNull(data,"f_param_role_id");
        if(f_param_role_id==null){return null;}
        String id_str = ","+f_param_role_id+",";
        List<Map<String,Object>> dList = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("id_str",id_str)
                        .Select("id")
                        .From(sys_role.class)
                        .Where("and INSTR(#{id_str}, CONCAT(CONCAT(',',ID),',')) > 0","id_str")
                        .GetFactor()
        );
        ArrayNode rList = mapper.createArrayNode();
        for(Map<String,Object> d : dList){
            ObjectNode r = mapper.createObjectNode();
            r.put("user_id",d.get("id").toString());
            r.put("user_type",userType);
            rList.add(r);
        }
        result = rList.toString();
        return result;
    }

    //参与者接口
    public String inter_zjsj( String jsonStr) {
        String userType = FlowType.node_user_type_zjsj;
        String result = "[]";

        System.out.println("【AAAA】 inter_zjsj - jsonStr:"+jsonStr);

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode data = null;
        try{
            data = (ObjectNode)mapper.readTree(jsonStr);
        }
        catch (IOException e) {
            e.printStackTrace();
            return result;
        }

        String previous_nodeins_id = FlowType.getJsonNodeItemTextNull(data,"previous_nodeins_id");
        if(previous_nodeins_id==null){return null;}
        Map<String, Object> pData = new HashMap<String,Object>();
        pData.put("nodeins_id",previous_nodeins_id);
        List<Map<String,Object>> dList = flowMapper.GetUserIdByNodeInsIdAndNodeinsUser_Zjsj(pData);
        ArrayNode rList = mapper.createArrayNode();
        for(Map<String,Object> d : dList){
            ObjectNode r = mapper.createObjectNode();
            r.put("user_id",d.get("user_id").toString());
            r.put("user_type",userType);
            rList.add(r);
        }
        result = rList.toString();
        return result;
    }

    //参与者接口
    public String inter_flow_creater( String jsonStr) {
        String result = "[]";

        System.out.println("【AAAA】 inter_flow_creater - jsonStr:"+jsonStr);

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode data = null;
        try{
            data = (ObjectNode)mapper.readTree(jsonStr);
        }
        catch (IOException e) {
            e.printStackTrace();
            return result;
        }

        String flowins_id = FlowType.getJsonNodeItemTextNull(data,"flowins_id");
        if(flowins_id==null){return null;}
        List<Map<String,Object>> dList = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("flowins_id",flowins_id)
                        .Select("sys_createuser AS id")
                        .From(fw_flowins.class)
                        .Where("and id  =#{flowins_id}","flowins_id")
                        .GetFactor()
        );
        ArrayNode rList = mapper.createArrayNode();
        for(Map<String,Object> d : dList){
            ObjectNode r = mapper.createObjectNode();
            r.put("user_id",d.get("id").toString());
            r.put("user_type",FlowType.node_user_type_user);
            rList.add(r);
        }
        result = rList.toString();
        return result;
    }

    //参与者接口
    public String inter_dynamic( String jsonStr) {
        String userType = FlowType.node_user_type_user;
        String result = "[]";

        System.out.println("【AAAA】 inter_dynamic - jsonStr:"+jsonStr);

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode data = null;
        try{
            data = (ObjectNode)mapper.readTree(jsonStr);
        }
        catch (IOException e) {
            e.printStackTrace();
            return result;
        }

        String dynamic_user_id = FlowType.getJsonNodeItemTextNull(data,"dynamic_user_id");
        if(dynamic_user_id==null){return null;}
        String id_str = ","+dynamic_user_id+",";
        List<Map<String,Object>> dList = coreMapper.USelectList(
                new DMaker().Selector
                        .putFactorItem("id_str",id_str)
                        .Select("id")
                        .From(sys_user.class)
                        .Where("and INSTR(#{id_str}, CONCAT(CONCAT(',',ID),',')) > 0","id_str")
                        .GetFactor()
        );
        ArrayNode rList = mapper.createArrayNode();
        for(Map<String,Object> d : dList){
            ObjectNode r = mapper.createObjectNode();
            r.put("user_id",d.get("id").toString());
            r.put("user_type",userType);
            rList.add(r);
        }
        result = rList.toString();
        return result;
    }

/////////////
}
